/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { getInputProps, useNamespace } from '@ibiz-template/vue3-util';
import { defineComponent, ref, watch } from 'vue';
import { clone, debounce } from '@ibiz-template/core';
import { AIParamsController } from './ai-params.controller';
import './ai-params.scss';

interface IAIParam {
  /**
   * @description 参数名
   * @type {string}
   * @memberof IAIParam
   */
  paramName: string;
  /**
   * @description 内容
   * @type {string}
   * @memberof IAIParam
   */
  content: string;
}

export const AIParams = defineComponent({
  name: 'AIParams',
  props: getInputProps<AIParamsController>(),
  emits: ['change'],
  setup(props, { emit }) {
    const ns = useNamespace('ai-params');
    const c: AIParamsController = props.controller;
    // 是否使用自定义
    const isCustom = ref(false);

    // 是否为合法参数字符串
    const isLegal = ref(true);

    // 参数字符串
    const paramStr = ref<string>('');

    // 参数数组
    const paramArr = ref<IAIParam[]>([]);

    /**
     * 抛值
     */
    const emitFunc = debounce(() => {
      emit('change', paramStr.value);
    }, 500);

    /**
     * @description 解析字符串为数组
     * @returns {*}  {void}
     */
    const parseStrToArray = (): void => {
      isLegal.value = true;
      const tempArray: IAIParam[] = [];

      const text = paramStr.value?.trim();

      // 空字符串处理
      if (!text) {
        paramArr.value = tempArray;
        return;
      }

      let index = 0;

      // 主解析循环
      while (index < text.length) {
        // 跳过空白字符
        if (text[index].trim() === '') {
          index++;
          continue;
        }

        // 尝试匹配开始标签
        const startMatch = text.slice(index).match(/^<(\w+)>/);
        if (!startMatch) {
          // 没有匹配到开始标签，说明有非法内容
          isCustom.value = true;
          isLegal.value = false;
          return;
        }

        const tagName = startMatch[1].toLowerCase();
        index += startMatch[0].length;

        // 检查标签名是否合法
        const isValidParam = c.AIParams.some(p => p.value === tagName);
        if (!isValidParam) {
          isCustom.value = true;
          isLegal.value = false;
          return;
        }

        // 查找对应的结束标签
        const endTag = `</${tagName}>`;
        const endIndex = text.indexOf(endTag, index);

        if (endIndex === -1) {
          // 没有找到匹配的结束标签
          isCustom.value = true;
          isLegal.value = false;
          return;
        }

        // 提取标签内容
        const content = text.slice(index, endIndex).trim();
        index = endIndex + endTag.length;

        // 添加到数组
        tempArray.push({
          paramName: tagName,
          content,
        });

        // 检查是否有嵌套的相同标签（这是不合法的）
        const nextStartIndex = text.indexOf(`<${tagName}>`, index);
        const nextEndIndex = text.indexOf(endTag, index);
        if (nextStartIndex !== -1 && nextStartIndex < nextEndIndex) {
          // 发现了嵌套的相同标签
          isCustom.value = true;
          isLegal.value = false;
          return;
        }
      }

      // 检查是否完全匹配了整个字符串
      if (index !== text.length) {
        // 还有未处理的字符
        const remaining = text.slice(index).trim();
        if (remaining.length > 0) {
          isCustom.value = true;
          isLegal.value = false;
          return;
        }
      }

      // 字符串完全合法
      paramArr.value = tempArray;
    };

    watch(
      () => props.value,
      newVal => {
        paramStr.value = newVal as string;
        parseStrToArray();
      },
      {
        immediate: true,
      },
    );

    /**
     * @description 解析数组为字符串
     * @returns {*}  {void}
     */
    const parseArrayToStr = (): void => {
      paramStr.value = paramArr.value
        .map(item => {
          return `<${item.paramName}>\n${item.content}\n</${item.paramName}>`;
        })
        .join('\n');
    };

    /**
     * @description 切换自定义
     */
    const onSwitchCustom = (): void => {
      isCustom.value = !isCustom.value;
    };

    /**
     * @description 参数改变
     */
    const onParamChange = (): void => {
      parseArrayToStr();
      emitFunc();
    };

    /**
     * @description 删除
     * @param {number} index
     * @returns {*}
     */
    const onDelete = (index: number): void => {
      paramArr.value.splice(index, 1);
      parseArrayToStr();
      emitFunc();
    };

    /**
     * @description 拷贝
     * @param {number} index
     */
    const onCopy = (index: number): void => {
      const tempCopy = clone(paramArr.value[index]);
      paramArr.value.splice(index, 0, tempCopy);
      parseArrayToStr();
      emitFunc();
    };

    /**
     * @description 添加项
     */
    const onAddItem = (): void => {
      paramArr.value.push({
        paramName: c.AIParams[0].value as string,
        content: '',
      });
      parseArrayToStr();
      emitFunc();
    };

    /**
     * @description 自定义变更
     */
    const onCustomChange = (): void => {
      parseStrToArray();
      emitFunc();
    };

    return {
      c,
      ns,
      isLegal,
      isCustom,
      paramStr,
      paramArr,
      onCopy,
      onDelete,
      onAddItem,
      onParamChange,
      onCustomChange,
      onSwitchCustom,
    };
  },
  render() {
    return (
      <div class={this.ns.b()}>
        {this.isCustom ? (
          <div class={this.ns.e('custom')}>
            <el-input
              rows={6}
              type='textarea'
              v-model={this.paramStr}
              disabled={this.disabled}
              readonly={this.readonly}
              onInput={this.onCustomChange}
            ></el-input>
          </div>
        ) : (
          <div class={this.ns.e('list')}>
            {this.paramArr.map((p, index) => {
              return (
                <div class={this.ns.e('list-item')}>
                  <el-select
                    v-model={p.paramName}
                    readonly={this.readonly}
                    disabled={this.disabled}
                    onChange={this.onParamChange}
                    class={this.ns.em('list-item', 'param-name')}
                  >
                    {{
                      default: () => {
                        return this.c.AIParams.map(pa => {
                          return (
                            <el-option
                              key={pa.value}
                              label={pa.text}
                              value={pa.value}
                            ></el-option>
                          );
                        });
                      },
                    }}
                  </el-select>
                  <el-input
                    rows={1}
                    type='textarea'
                    v-model={p.content}
                    disabled={this.disabled}
                    readonly={this.readonly}
                    onInput={this.onParamChange}
                    class={this.ns.em('list-item', 'param-content')}
                  ></el-input>
                  <div class={this.ns.em('list-item', 'actions')}>
                    <el-button
                      size='small'
                      title='删除'
                      disabled={this.disabled}
                      onClick={() => this.onDelete(index)}
                      class={this.ns.em('list-item', 'close')}
                    >
                      <ion-icon name='close-outline'></ion-icon>
                    </el-button>
                    <el-button
                      size='small'
                      title='拷贝'
                      disabled={this.disabled}
                      onClick={() => this.onCopy(index)}
                      class={this.ns.em('list-item', 'copy')}
                    >
                      <ion-icon name='copy-outline'></ion-icon>
                    </el-button>
                  </div>
                </div>
              );
            })}
          </div>
        )}
        <div class={this.ns.e('footer')}>
          <el-button
            size='small'
            disabled={!this.isLegal}
            onClick={this.onSwitchCustom}
            title={this.isCustom ? '关闭自定义' : '开启自定义'}
          >
            {this.isCustom ? '关闭自定义' : '开启自定义'}
          </el-button>
          {!this.isCustom && !this.readonly && (
            <el-button
              size='small'
              title='添加'
              onClick={this.onAddItem}
              disabled={this.disabled}
            >
              <ion-icon name='add-outline'></ion-icon>
            </el-button>
          )}
        </div>
      </div>
    );
  },
});
